package cn.jee.redis;

import cn.jee.redis.domain.Stu;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;

public class StuMis {
  private Jedis jedis;

  public StuMis() {
    jedis = new Jedis("localhost", 6379); // 连接到本地 Redis 服务器
  }

  // 清空数据库
  public void clear() {
    jedis.flushAll();
  }

  // 产生一个学生学号
  public long newId() {
    return jedis.incr("stu:nextId"); // 使用 Redis 的自增键生成唯一学号
  }

  // 添加学生信息
  public void add(Stu stu) {
    long id = newId(); // 生成学号
    stu.setId(id); // 设置学号

    // 将学生信息存储到 hash 表中
    jedis.hmset("stu:" + id, stu.toMap());

    // 将 Java 成绩存储到有序集合中
    jedis.zadd("java:grades", stu.getJava(), String.valueOf(id));

    // 将 Math 成绩存储到有序集合中
    jedis.zadd("math:grades", stu.getMath(), String.valueOf(id));
  }

  // 获取数学成绩最高的 5 个人的姓名
  public String[] top5ByMath() {
    List<String> topIds = jedis.zrevrange("math:grades", 0, 4); // 获取数学成绩最高的 5 个学号
    String[] names = new String[topIds.size()];

    for (int i = 0; i < topIds.size(); i++) {
      // 根据学号获取学生信息中的姓名
      names[i] = jedis.hget("stu:" + topIds.get(i), "username");
    }

    return names;
  }

  // 获取 Java 成绩在 min 和 max 之间的学生成绩
  public double[] betweenJava(double min, double max) {
    List<String> ids = jedis.zrangeByScore("java:grades", min, max); // 获取 Java 成绩在范围内的学号
    double[] grades = new double[ids.size()];

    for (int i = 0; i < ids.size(); i++) {
      // 根据学号获取学生信息中的 Java 成绩
      grades[i] = Double.parseDouble(jedis.hget("stu:" + ids.get(i), "java"));
    }

    return grades;
  }

  // 按学号查找学生信息
  public Stu findById(long id) {
    String key = "stu:" + id;
    if (!jedis.exists(key)) {
      return null; // 如果学号不存在，返回 null
    }

    // 从 hash 表中获取学生信息
    Stu stu = new Stu();
    stu.setId(id);
    stu.setUsername(jedis.hget(key, "username"));
    stu.setJava(Double.parseDouble(jedis.hget(key, "java")));
    stu.setMath(Double.parseDouble(jedis.hget(key, "math")));

    return stu;
  }

  // 按 Java 成绩从低到高分页查询
  public List<Stu> pageByJava(int page, int size) {
    int start = (page - 1) * size; // 计算分页的起始位置
    int end = start + size - 1; // 计算分页的结束位置

    List<String> ids = jedis.zrange("java:grades", start, end); // 获取分页范围内的学号
    List<Stu> students = new ArrayList<>();

    for (String id : ids) {
      // 根据学号获取学生信息
      Stu stu = findById(Long.parseLong(id));
      if (stu != null) {
        students.add(stu);
      }
    }

    return students;
  }
}